package net.gdface.facedb;

import java.io.File;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import com.gitee.l0km.com4j.base.InterfaceDecorator;
import com.google.common.base.Throwables;

import gu.sql2java.manager.Managers;
import gu.sql2java.manager.store.BinaryStoreTable;
import gu.sql2java.store.LocalBinaryStore;
import gu.sql2java.store.URLStore;
import net.gdface.facedb.db.Constant;

import static net.gdface.facedb.PropertyUtil.loadPropertiesInUserHome;
import static gu.sql2java.manager.Managers.registerCacheManager;
import static net.gdface.facedb.PropertyUtil.loadProperties;
import static net.gdface.facedb.PropertyUtil.normalize;

/**
 * 全局初始化数据库访问对象(TableManager)
 * @author guyadong
 *
 */
public class TableManagerInitializer implements LocalConstant,Constant{
	final BinaryStoreTable storeTable;
	final LocalBinaryStore storeLocal;	
	final Properties config;
	final URLStore storeInstance;
	final StoreType storeTarget;
	private boolean coreDebug = false;
	public static final TableManagerInitializer INSTANCE = new TableManagerInitializer();
	private TableManagerInitializer() {
		if(null != TableManagerInitializerSupport.properties){	
			config = normalize(TableManagerInitializerSupport.properties);
		}else if(null != TableManagerInitializerSupport.localPropertiesFile){
			// 向底层数据库操作类注入当前项目使用的数据库连接配置
			config = loadProperties(TableManagerInitializerSupport.localPropertiesFile);
		}else{
			// 向底层数据库操作类注入当前项目使用的数据库连接配置
	        config = loadPropertiesInUserHome(HOME_FOLDER + "/" + PROPFILE);
		}
		coreDebug = Boolean.valueOf(config.getProperty(SYSLOG_COREDEBUG, "false"));
		// 允许输出调试信息
		if(coreDebug){
			Managers.setDebug(true);
			InterfaceDecorator.setDebug(true);
		}
		config.setProperty(JdbcProperty.ALIAS.key, ALIAS_NAME);

        if(!config.stringPropertyNames().isEmpty()){
        	config.list(System.out);
    		// 创建数据库连接实例
    		Managers.createInstance(config);
        }
        
        storeTable = new BinaryStoreTable("fd_store","data", "extension", null);
        File storeRoot = new File(config.getProperty(STORE_LOCAL_ROOT, DEFAULT_LBS_ROOT));
        storeLocal = LocalBinaryStore.SINGLETON.setStoreRoot(storeRoot);
        storeTarget = StoreType.valueOf(config.getProperty(STORE_TARGET,DEFAULT_STORE_TARGET));

        switch (storeTarget) {
        case DB:
        	storeInstance = storeTable;
        	break;
        case FILE:
        	storeInstance = storeLocal;
        	break;
        default:
        	throw new IllegalArgumentException(String.format("INVALID PROPERTY %s:%s",STORE_TARGET,storeTarget));
        }

        Integer duration = Integer.valueOf(config.getProperty(DB_CACHE_DURATION, "10"));
        Integer maximumSize = Integer.valueOf(config.getProperty(DB_CACHE_MAXIMUMSIZE, "10000"));        
		// 配置cache参数
		registerCacheManager("fd_face",com.gitee.l0km.aocache.UpdateStrategy.ALWAYS,maximumSize,duration,TimeUnit.MINUTES);
		//registerCacheManager("fd_image",UpdateStrategy.always,maximumSize,duration,TimeUnit.MINUTES);		 
		registerCacheManager("fd_feature",com.gitee.l0km.aocache.UpdateStrategy.REFRESH,maximumSize,duration,TimeUnit.MINUTES);
	}	
	public TableManagerInitializer init(){
		installURLStreamHandlerFactory();
		return this;
	}
	/**
	 * 安装自定义 {@link java.net.URLStreamHandlerFactory} 实例<br>
	 * 应用层应该确保在其他第三方式库执行过{@link java.net.URL#setURLStreamHandlerFactory(java.net.URLStreamHandlerFactory)}后再调用本方法,
	 * 否则会导致第三方库(如tomcat)执行异常
	 */
	private void installURLStreamHandlerFactory(){
		try {
			storeTable.intall();
			storeLocal.intall();
		} catch (Exception e) {
			Throwables.throwIfUnchecked(e);
			throw new RuntimeException(e);
		}
	}
}
